varying vec3 pColor;
varying vec4 pShadowCoord;			//	coordinate in the shadow map

varying vec3 pEyeVec;			//	vertex_to_eye vector
varying vec3 pLightDir;			//	light_to_vertex vector
varying vec3 pNormal;

uniform sampler2DShadow depthMap;	//	depth map

uniform float pixelOffset;

float lookUp(vec2 offset)
{
	vec4 shadowCoord = pShadowCoord + vec4(offset.x*pixelOffset*pShadowCoord.w, offset.y*pixelOffset*pShadowCoord.w, -0.005, 0);
	return textureProj(depthMap, shadowCoord);	
}

void main() 
{		
	float shadow = 1.0;
	if (pShadowCoord.w > 0)
	{
		float offset = 0.5;
		shadow = lookUp(vec2(-offset, -offset)) + lookUp(vec2(-offset, 0)) + lookUp(vec2(-offset, offset))
				+ lookUp(vec2(0, -offset)) + lookUp(vec2(0, 0)) + lookUp(vec2(0, offset))
				+ lookUp(vec2(offset, -offset)) + lookUp(vec2(offset, 0)) + lookUp(vec2(offset, offset));
		shadow = shadow/9;	
		if (shadow < 0.2)
			shadow = 0.2;
	}

	vec3 final_color = 0.1 * pColor;	//	ambient color
	vec3 N = normalize(pNormal);
	vec3 L = normalize(pLightDir);
	float dotTerm = dot(N, -L);
	if (dotTerm > 0.0)
    {
		final_color += pColor * 0.3 * dotTerm;	//	diffuse color
		vec3 E = normalize(pEyeVec);
		vec3 R = reflect(L, N);		//	reflect light
		float dotTerm2 = dot(R, E);
		if (dotTerm2 > 0.0)
			final_color += pColor * 1.0 * pow(dotTerm2, 10.0);		//	specular color
    }

	
	gl_FragColor =	vec4(shadow * final_color, 1.0);
} 
